package com.ms.module.wechat.clear.repository;

import android.os.SystemClock;
import android.util.Log;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.chad.library.adapter.base.entity.node.BaseNode;
import com.ms.module.wechat.clear.R;
import com.ms.module.wechat.clear.fragment.adapter.node.DownChildNode;
import com.ms.module.wechat.clear.fragment.adapter.node.DownGroupNode;
import com.ms.module.wechat.clear.fragment.adapter.node.UpChildNode;
import com.ms.module.wechat.clear.fragment.adapter.node.UpGroupNode;
import com.ms.module.wechat.clear.fragment.adapter.node.FileChildNode;
import com.ms.module.wechat.clear.fragment.adapter.node.FileHeaderNode;
import com.ms.module.wechat.clear.utils.ByteSizeToStringUnitUtils;
import com.ms.module.wechat.clear.utils.WeChatClearUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class WeChatScanDataRepository {

    private static final String TAG = "WeChatScanDataRepositor";

    /**
     * 时间 格式化 格式
     */
    private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 私有化构造
     */
    private WeChatScanDataRepository() {
    }

    private static final WeChatScanDataRepository instance = new WeChatScanDataRepository();

    /**
     * 单例设计
     *
     * @return
     */
    public static WeChatScanDataRepository getInstance() {
        return instance;
    }

    // 朋友圈缓冲
    public final List<String> friendList = new ArrayList<>();

    public final List<String> cacheList = new ArrayList<>();

    // 垃圾文件
    public final List<String> rubbishList = new ArrayList<>();
    // video
    public final List<String> videoList = new ArrayList<>();
    // image
    public final List<String> imageList = new ArrayList<>();
    // voice
    public final List<String> voiceList = new ArrayList<>();
    // file
    public final List<String> fileList = new ArrayList<>();
    // emoji
    public final List<String> emojiList = new ArrayList<>();


    public List<String> getFriendList() {
        return friendList;
    }

    public List<String> getCacheList() {
        return cacheList;
    }

    public List<String> getRubbishList() {
        return rubbishList;
    }

    public List<String> getVideoList() {
        return videoList;
    }

    public List<String> getVoiceList() {
        return voiceList;
    }

    public List<String> getImageList() {
        return imageList;
    }

    public List<String> getFileList() {
        return fileList;
    }

    public List<String> getEmojiList() {
        return emojiList;
    }

    // 扫描文件总大小
    private MutableLiveData<Long> mutableLiveDataTotalScanGarbageSize;

    public MutableLiveData<Long> getMutableLiveDataTotalScanGarbageSize() {
        return mutableLiveDataTotalScanGarbageSize;
    }

    public void setMutableLiveDataTotalScanGarbageSize(MutableLiveData<Long> mutableLiveDataTotalScanGarbageSize) {
        this.mutableLiveDataTotalScanGarbageSize = mutableLiveDataTotalScanGarbageSize;
    }

    // 扫描总垃圾大小
    private volatile long totalScanGarbageSize = 0;

    /**
     * 接收文件
     *
     * @return
     */
    public LiveData<List<String>> receiveFile() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {
                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(ObservableEmitter<List<String>> emitter) throws Exception {


                        long start = System.currentTimeMillis();

                        List<String> result = WeChatClearUtils.receiveFiles();
                        fileList.clear();
                        fileList.addAll(result);
                        for (String it : fileList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }

                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }

                            @Override
                            public void onNext(List<String> list) {
                                postValue(list);
                            }

                            @Override
                            public void onError(Throwable e) {
                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }


    /**
     * 垃圾文件
     *
     * @return
     */
    public LiveData<List<String>> rubbish() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {
                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<String>> emitter) throws Exception {


                        long start = System.currentTimeMillis();

                        List<String> rubbish = WeChatClearUtils.rubbish();
                        rubbishList.clear();
                        rubbishList.addAll(rubbish);

                        List<String> cache = WeChatClearUtils.cache();

                        cacheList.clear();
                        cacheList.addAll(cache);

                        List<String> friendCache = WeChatClearUtils.friendCache();
                        friendList.clear();
                        friendList.addAll(friendCache);


                        for (String it : rubbishList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        for (String it : cacheList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        for (String it : friendList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        List<String> result = new ArrayList<>();
                        result.addAll(rubbish);
                        result.addAll(cache);
                        result.addAll(friendCache);

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }

                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<String> result) {
                                postValue(result);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });


            }
        };
    }


    /**
     * 视频文件
     *
     * @return
     */
    public LiveData<List<String>> video() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {

                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<String>> emitter) throws Exception {

                        long start = System.currentTimeMillis();

                        List<String> result = WeChatClearUtils.video();
                        videoList.clear();
                        videoList.addAll(result);
                        for (String it : videoList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }

                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<String> result) {
                                postValue(result);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });

            }
        };
    }

    /**
     * 图片
     *
     * @return
     */
    public LiveData<List<String>> image() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {
                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<String>> emitter) throws Exception {


                        long start = System.currentTimeMillis();

                        List<String> result = WeChatClearUtils.image();
                        imageList.clear();
                        imageList.addAll(result);
                        for (String it : imageList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }
                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<String> result) {
                                postValue(result);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });

            }
        };
    }


    /**
     * 聊天语音
     *
     * @return
     */
    public LiveData<List<String>> voice() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {

                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<String>> emitter) throws Exception {

                        long start = System.currentTimeMillis();

                        List<String> result = WeChatClearUtils.voice2();
                        voiceList.clear();
                        voiceList.addAll(result);

                        for (String it : voiceList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }

                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<String> result) {
                                postValue(result);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });


            }
        };
    }

    /**
     * 聊天表情
     *
     * @return
     */
    public LiveData<List<String>> emoji() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {

                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<String>> emitter) throws Exception {
                        long start = System.currentTimeMillis();

                        // 可选过滤的和不过滤的
                        List<String> result = WeChatClearUtils.emojiFilter();
                        emojiList.clear();
                        emojiList.addAll(result);
                        for (String it : emojiList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }

                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<String> result) {
                                postValue(result);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }


    /**
     * 缓冲
     *
     * @return
     */
    public LiveData<List<String>> cache() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {

                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<String>> emitter) throws Exception {

                        long start = System.currentTimeMillis();

                        List<String> result = WeChatClearUtils.cache();
                        cacheList.clear();
                        cacheList.addAll(result);
                        for (String it : cacheList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }

                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<String> result) {
                                postValue(result);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }


    /**
     * 盆友圈缓冲
     *
     * @return
     */
    public LiveData<List<String>> friendCache() {
        return new LiveData<List<String>>() {
            @Override
            protected void onActive() {

                Observable.create(new ObservableOnSubscribe<List<String>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<String>> emitter) throws Exception {

                        long start = System.currentTimeMillis();

                        List<String> result = WeChatClearUtils.friendCache();
                        friendList.clear();
                        friendList.addAll(result);
                        for (String it : friendList) {
                            totalScanGarbageSize += new File(it).length();
                            mutableLiveDataTotalScanGarbageSize.postValue(totalScanGarbageSize);
                        }

                        long end = System.currentTimeMillis();

                        long timeConsuming = end - start;

                        if (timeConsuming < 3000) {
                            SystemClock.sleep(3000 - timeConsuming);
                        }

                        emitter.onNext(result);
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<String>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<String> result) {
                                postValue(result);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }


    private List<BaseNode> listBaseNodesDatas = new ArrayList<>();


    private boolean is30Min() {

        String clear_timemillis = SharedPreferencesData.getInstance().get("clear_timemillis");
        if (null == clear_timemillis || "".equals(clear_timemillis)) {
            Long time = Long.valueOf(clear_timemillis);
            long currentTimeMillis = System.currentTimeMillis();

            if (currentTimeMillis - time < 1000 * 60 * 30) {
                // 更新存入时间戳
                return true;
            }

        }

        return false;
    }


    /**
     * 扫描完成 上面部分聚合数据
     *
     * @return
     */
    public LiveData<List<BaseNode>> getDatas() {
        return new LiveData<List<BaseNode>>() {
            @Override
            protected void onActive() {

                Observable.create(new ObservableOnSubscribe<List<BaseNode>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<BaseNode>> emitter) throws Exception {

                        List<BaseNode> groupDatas = new ArrayList<>();
                        List<BaseNode> upChildDatas = new ArrayList<>();
                        List<BaseNode> downChildDatas = new ArrayList<>();


                        long rubbishListfileLength = WeChatClearUtils.getFileLength(rubbishList);
                        long cacheListfileLength = WeChatClearUtils.getFileLength(cacheList);
                        long friendListfileLength = WeChatClearUtils.getFileLength(friendList);


                        long randomValue0 = 0;
                        long randomValue1 = 0;
                        long randomValue2 = 0;


                        if (rubbishListfileLength == 0) {
                            if (SharedPreferencesData.is30Min()) {
                                upChildDatas.add(new UpChildNode("垃圾文件", R.drawable.image_trash_can, WeChatClearUtils.getFileLength(rubbishList), true, rubbishList));
                            } else {
                                randomValue0 = SharedPreferencesData.random();
                                upChildDatas.add(new UpChildNode("垃圾文件", R.drawable.image_trash_can, randomValue0, true, rubbishList));
                            }

                        } else {
                            upChildDatas.add(new UpChildNode("垃圾文件", R.drawable.image_trash_can, WeChatClearUtils.getFileLength(rubbishList), true, rubbishList));
                        }

                        if (cacheListfileLength == 0) {
                            if (SharedPreferencesData.is30Min()) {
                                upChildDatas.add(new UpChildNode("缓冲文件", R.drawable.image_cache, WeChatClearUtils.getFileLength(cacheList), true, cacheList));
                            } else {
                                randomValue1 = SharedPreferencesData.random();
                                upChildDatas.add(new UpChildNode("缓冲文件", R.drawable.image_cache, randomValue1, true, cacheList));
                            }

                        } else {
                            upChildDatas.add(new UpChildNode("缓冲文件", R.drawable.image_cache, WeChatClearUtils.getFileLength(cacheList), true, cacheList));
                        }


                        if (friendListfileLength == 0) {

                            if (SharedPreferencesData.is30Min()) {
                                upChildDatas.add(new UpChildNode("朋友圈缓冲", R.drawable.image_firend, WeChatClearUtils.getFileLength(friendList), true, friendList));
                            } else {
                                randomValue2 = SharedPreferencesData.random();
                                upChildDatas.add(new UpChildNode("朋友圈缓冲", R.drawable.image_firend, randomValue2, true, friendList));
                            }

                        } else {
                            upChildDatas.add(new UpChildNode("朋友圈缓冲", R.drawable.image_firend, WeChatClearUtils.getFileLength(friendList), true, friendList));

                        }


//                        upChildDatas.add(new UpChildNode("垃圾文件", R.drawable.image_trash_can, WeChatClearUtils.getFileLength(rubbishList), true, rubbishList));
//                        upChildDatas.add(new UpChildNode("缓冲文件", R.drawable.image_cache, WeChatClearUtils.getFileLength(cacheList), true, cacheList));
//                        upChildDatas.add(new UpChildNode("朋友圈缓冲", R.drawable.image_firend, WeChatClearUtils.getFileLength(friendList), true, friendList));


                        downChildDatas.add(new DownChildNode("聊天小视频", R.drawable.image_video, WeChatClearUtils.getFileLength(videoList)));
                        downChildDatas.add(new DownChildNode("聊天图片", R.drawable.image_image, WeChatClearUtils.getFileLength(imageList)));
                        downChildDatas.add(new DownChildNode("聊天语音", R.drawable.image_voice, WeChatClearUtils.getFileLength(voiceList)));
                        downChildDatas.add(new DownChildNode("文件", R.drawable.image_file, WeChatClearUtils.getFileLength(fileList)));
                        downChildDatas.add(new DownChildNode("聊天表情包", R.drawable.image_emoji, WeChatClearUtils.getFileLength(emojiList)));


                        if (SharedPreferencesData.is30Min()) {
                            groupDatas.add(new UpGroupNode(upChildDatas, WeChatClearUtils.getFileLength(rubbishList, cacheList, friendList), true));

                        } else {
                            groupDatas.add(new UpGroupNode(upChildDatas, randomValue0 + randomValue1 + randomValue2, true));
                        }


                        groupDatas.add(new DownGroupNode(downChildDatas, WeChatClearUtils.getFileLength(videoList, imageList, voiceList, fileList, emojiList)));

                        emitter.onNext(groupDatas);
                    }
                }).subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<BaseNode>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<BaseNode> baseNodes) {
                                postValue(baseNodes);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }


    private List<BaseNode> listBaseNodesImage = new ArrayList<>();

    /**
     * 图片详情
     *
     * @return
     */
    public LiveData<List<BaseNode>> getImageData() {
        return new LiveData<List<BaseNode>>() {
            @Override
            protected void onActive() {

                Observable.create(new ObservableOnSubscribe<List<BaseNode>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<BaseNode>> emitter) throws Exception {

                        // 时间为Key,集合为同一天的文件
                        Map<String, List<String>> mapDatePaths = new TreeMap<>();

                        String dateKey = "";

                        long currentTimeMillis = System.currentTimeMillis();
                        long currentTimeMillis7 = currentTimeMillis - 1000 * 60 * 60 * 24 * 7;
                        long currentTimeMillis30 = currentTimeMillis - 1000 * 60 * 60 * 24 * 30;


                        // 遍历 视频集合列表
                        for (String it : imageList) {

                            // 获取文件时间戳
                            long fileLastModifiedTime = WeChatClearUtils.getFileLastModifiedTime(it);


                            if (fileLastModifiedTime > currentTimeMillis7) {
                                dateKey = "1周内";
                            } else if (fileLastModifiedTime < currentTimeMillis7 && fileLastModifiedTime > currentTimeMillis30) {
                                dateKey = "1个月内";
                            } else {
                                dateKey = "1个月以前";
                            }

                            // 判断集合中是否含有此时间key
                            if (mapDatePaths.containsKey(dateKey)) {
                                //将同一天的文件加入到一个集合
                                mapDatePaths.get(dateKey).add(it);
                            } else {
                                // 存入时间key 和 数据源实例
                                mapDatePaths.put(dateKey, new ArrayList<>());
                                mapDatePaths.get(dateKey).add(it);
                            }
                        }


                        mapDatePaths = ((TreeMap) mapDatePaths).descendingMap();
                        Set<String> keySet = mapDatePaths.keySet();

                        List<BaseNode> baseNodes = new ArrayList<>();

                        for (String it : keySet) {

                            // 获取 一天时间里的所有文件路径
                            List<String> paths = mapDatePaths.get(it);

                            List<BaseNode> childNodes = new ArrayList<>();
                            for (String it1 : paths) {
                                childNodes.add(new FileChildNode(it1, true, WeChatClearUtils.getFileLength(it1)));
                            }
                            baseNodes.add(new FileHeaderNode(it, WeChatClearUtils.getFileLength(paths), paths.size(), true, childNodes));
                        }
                        emitter.onNext(baseNodes);
                    }
                }).observeOn(Schedulers.io())
                        .subscribe(new Observer<List<BaseNode>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<BaseNode> baseNodes) {
                                postValue(baseNodes);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });


            }
        };
    }


    private List<BaseNode> listBaseNodesEmoji = new ArrayList<>();

    /**
     * 表情
     *
     * @return
     */
    public LiveData<List<BaseNode>> getEmojiData() {
        return new LiveData<List<BaseNode>>() {
            @Override
            protected void onActive() {
                Observable.create(new ObservableOnSubscribe<List<BaseNode>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<BaseNode>> emitter) throws Exception {

                        // 时间为Key,集合为同一天的文件
                        Map<String, List<String>> mapDatePaths = new TreeMap<>();

                        String dateKey = "";

                        long currentTimeMillis = System.currentTimeMillis();
                        long currentTimeMillis7 = currentTimeMillis - 1000 * 60 * 60 * 24 * 7;
                        long currentTimeMillis30 = currentTimeMillis - 1000 * 60 * 60 * 24 * 30;
                        long currentTimeMillis90 = currentTimeMillis - 1000 * 60 * 60 * 24 * 90;
                        long currentTimeMillis180 = currentTimeMillis - 1000 * 60 * 60 * 24 * 180;
                        long currentTimeMillis365 = currentTimeMillis - 1000 * 60 * 60 * 24 * 365;
                        long currentTimeMillis730 = currentTimeMillis - 1000 * 60 * 60 * 24 * 730;


                        // 遍历 视频集合列表
                        for (String it : emojiList) {

                            // 获取文件时间戳
                            long fileLastModifiedTime = WeChatClearUtils.getFileLastModifiedTime(it);


                            if (fileLastModifiedTime > currentTimeMillis7) {
                                dateKey = "1周内";
                            } else if (fileLastModifiedTime < currentTimeMillis7 && fileLastModifiedTime > currentTimeMillis30) {
                                dateKey = "1个月内";
                            } else {
                                dateKey = "1个月以前";
                            }

                            // 判断集合中是否含有此时间key
                            if (mapDatePaths.containsKey(dateKey)) {
                                //将同一天的文件加入到一个集合
                                mapDatePaths.get(dateKey).add(it);
                            } else {
                                // 存入时间key 和 数据源实例
                                mapDatePaths.put(dateKey, new ArrayList<>());
                                mapDatePaths.get(dateKey).add(it);
                            }
                        }
                        mapDatePaths = ((TreeMap) mapDatePaths).descendingMap();
                        Set<String> keySet = mapDatePaths.keySet();

                        listBaseNodesEmoji.clear();

                        for (String it : keySet) {


                            Log.e(TAG, "subscribe: " + it);


                            // 获取 一天时间里的所有文件路径
                            List<String> paths = mapDatePaths.get(it);

                            List<BaseNode> childNodes = new ArrayList<>();
                            for (String it1 : paths) {
                                childNodes.add(new FileChildNode(it1, true, WeChatClearUtils.getFileLength(it1)));
                            }
                            listBaseNodesEmoji.add(new FileHeaderNode(it, WeChatClearUtils.getFileLength(paths), paths.size(), true, childNodes));
                        }
                        emitter.onNext(listBaseNodesEmoji);
                    }
                }).observeOn(Schedulers.io())
                        .subscribe(new Observer<List<BaseNode>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<BaseNode> baseNodes) {
                                postValue(baseNodes);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }


    private List<BaseNode> listBaseNodesFile = new ArrayList<>();


    /**
     * 文件
     *
     * @return
     */
    public LiveData<List<BaseNode>> getFileData() {
        return new LiveData<List<BaseNode>>() {
            @Override
            protected void onActive() {
                Observable.create(new ObservableOnSubscribe<List<BaseNode>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<BaseNode>> emitter) throws Exception {


                        // 时间为Key,集合为同一天的文件
                        Map<String, List<String>> mapDatePaths = new TreeMap<>();

                        String dateKey = "";

                        long currentTimeMillis = System.currentTimeMillis();
                        long currentTimeMillis7 = currentTimeMillis - 1000 * 60 * 60 * 24 * 7;
                        long currentTimeMillis30 = currentTimeMillis - 1000 * 60 * 60 * 24 * 30;
                        long currentTimeMillis90 = currentTimeMillis - 1000 * 60 * 60 * 24 * 90;
                        long currentTimeMillis180 = currentTimeMillis - 1000 * 60 * 60 * 24 * 180;
                        long currentTimeMillis365 = currentTimeMillis - 1000 * 60 * 60 * 24 * 365;
                        long currentTimeMillis730 = currentTimeMillis - 1000 * 60 * 60 * 24 * 730;


                        // 遍历 视频集合列表
                        for (String it : fileList) {

                            // 获取文件时间戳
                            long fileLastModifiedTime = WeChatClearUtils.getFileLastModifiedTime(it);


                            if (fileLastModifiedTime > currentTimeMillis7) {
                                dateKey = "1周内";
                            } else if (fileLastModifiedTime < currentTimeMillis7 && fileLastModifiedTime > currentTimeMillis30) {
                                dateKey = "1个月内";
                            } else {
                                dateKey = "1个月以前";
                            }

                            // 判断集合中是否含有此时间key
                            if (mapDatePaths.containsKey(dateKey)) {
                                //将同一天的文件加入到一个集合
                                mapDatePaths.get(dateKey).add(it);
                            } else {
                                // 存入时间key 和 数据源实例
                                mapDatePaths.put(dateKey, new ArrayList<>());
                                mapDatePaths.get(dateKey).add(it);
                            }
                        }
                        mapDatePaths = ((TreeMap) mapDatePaths).descendingMap();
                        Set<String> keySet = mapDatePaths.keySet();

                        List<BaseNode> baseNodes = new ArrayList<>();

                        for (String it : keySet) {

                            // 获取 一天时间里的所有文件路径
                            List<String> paths = mapDatePaths.get(it);

                            List<BaseNode> childNodes = new ArrayList<>();
                            for (String it1 : paths) {
                                childNodes.add(new FileChildNode(it1, true, WeChatClearUtils.getFileLength(it1)));
                            }
                            baseNodes.add(new FileHeaderNode(it, WeChatClearUtils.getFileLength(paths), paths.size(), true, childNodes));
                        }
                        emitter.onNext(baseNodes);


                    }
                }).observeOn(Schedulers.io())
                        .subscribe(new Observer<List<BaseNode>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<BaseNode> baseNodes) {
                                postValue(baseNodes);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });


            }
        };
    }

    private List<BaseNode> listBaseNodesVoice = new ArrayList<>();


    /**
     * 语音
     *
     * @return
     */
    public LiveData<List<BaseNode>> getVoiceData() {
        return new LiveData<List<BaseNode>>() {
            @Override
            protected void onActive() {


                Observable.create(new ObservableOnSubscribe<List<BaseNode>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<BaseNode>> emitter) throws Exception {


                        // 时间为Key,集合为同一天的文件
                        Map<String, List<String>> mapDatePaths = new TreeMap<>();

                        String dateKey = "";

                        long currentTimeMillis = System.currentTimeMillis();
                        long currentTimeMillis7 = currentTimeMillis - 1000 * 60 * 60 * 24 * 7;
                        long currentTimeMillis30 = currentTimeMillis - 1000 * 60 * 60 * 24 * 30;
                        long currentTimeMillis90 = currentTimeMillis - 1000 * 60 * 60 * 24 * 90;
                        long currentTimeMillis180 = currentTimeMillis - 1000 * 60 * 60 * 24 * 180;
                        long currentTimeMillis365 = currentTimeMillis - 1000 * 60 * 60 * 24 * 365;
                        long currentTimeMillis730 = currentTimeMillis - 1000 * 60 * 60 * 24 * 730;


                        // 遍历 视频集合列表
                        for (String it : voiceList) {

                            // 获取文件时间戳
                            long fileLastModifiedTime = WeChatClearUtils.getFileLastModifiedTime(it);


                            if (fileLastModifiedTime > currentTimeMillis7) {
                                dateKey = "1周内";
                            } else if (fileLastModifiedTime < currentTimeMillis7 && fileLastModifiedTime > currentTimeMillis30) {
                                dateKey = "1个月内";
                            } else {
                                dateKey = "1个月以前";
                            }

                            // 判断集合中是否含有此时间key
                            if (mapDatePaths.containsKey(dateKey)) {
                                //将同一天的文件加入到一个集合
                                mapDatePaths.get(dateKey).add(it);
                            } else {
                                // 存入时间key 和 数据源实例
                                mapDatePaths.put(dateKey, new ArrayList<>());
                                mapDatePaths.get(dateKey).add(it);
                            }
                        }
                        mapDatePaths = ((TreeMap) mapDatePaths).descendingMap();
                        Set<String> keySet = mapDatePaths.keySet();

                        List<BaseNode> baseNodes = new ArrayList<>();

                        for (String it : keySet) {

                            // 获取 一天时间里的所有文件路径
                            List<String> paths = mapDatePaths.get(it);

                            List<BaseNode> childNodes = new ArrayList<>();
                            for (String it1 : paths) {
                                childNodes.add(new FileChildNode(it1, true, WeChatClearUtils.getFileLength(it1)));
                            }
                            baseNodes.add(new FileHeaderNode(it, WeChatClearUtils.getFileLength(paths), paths.size(), true, childNodes));
                        }
                        emitter.onNext(baseNodes);
                    }
                }).observeOn(Schedulers.io())
                        .subscribe(new Observer<List<BaseNode>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<BaseNode> baseNodes) {
                                postValue(baseNodes);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }


    private List<BaseNode> listBaseNodeVideo = new ArrayList<>();

    /**
     * 视频
     *
     * @return
     */
    public LiveData<List<BaseNode>> getVideoData() {
        return new LiveData<List<BaseNode>>() {
            @Override
            protected void onActive() {
                Observable.create(new ObservableOnSubscribe<List<BaseNode>>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<List<BaseNode>> emitter) throws Exception {
                        // 时间为Key,集合为同一天的文件
                        Map<String, List<String>> mapDatePaths = new TreeMap<>();

                        String dateKey = "";

                        long currentTimeMillis = System.currentTimeMillis();
                        long currentTimeMillis7 = currentTimeMillis - 1000 * 60 * 60 * 24 * 7;
                        long currentTimeMillis30 = currentTimeMillis - 1000 * 60 * 60 * 24 * 30;
                        long currentTimeMillis90 = currentTimeMillis - 1000 * 60 * 60 * 24 * 90;
                        long currentTimeMillis180 = currentTimeMillis - 1000 * 60 * 60 * 24 * 180;
                        long currentTimeMillis365 = currentTimeMillis - 1000 * 60 * 60 * 24 * 365;
                        long currentTimeMillis730 = currentTimeMillis - 1000 * 60 * 60 * 24 * 730;


                        // 遍历 视频集合列表
                        for (String it : videoList) {

                            // 获取文件时间戳
                            long fileLastModifiedTime = WeChatClearUtils.getFileLastModifiedTime(it);


                            if (fileLastModifiedTime > currentTimeMillis7) {
                                dateKey = "1周内";
                            } else if (fileLastModifiedTime < currentTimeMillis7 && fileLastModifiedTime > currentTimeMillis30) {
                                dateKey = "1个月内";
                            } else {
                                dateKey = "1个月以前";
                            }

                            // 判断集合中是否含有此时间key
                            if (mapDatePaths.containsKey(dateKey)) {
                                //将同一天的文件加入到一个集合
                                mapDatePaths.get(dateKey).add(it);
                            } else {
                                // 存入时间key 和 数据源实例
                                mapDatePaths.put(dateKey, new ArrayList<>());
                                mapDatePaths.get(dateKey).add(it);
                            }
                        }
                        mapDatePaths = ((TreeMap) mapDatePaths).descendingMap();
                        Set<String> keySet = mapDatePaths.keySet();

                        List<BaseNode> baseNodes = new ArrayList<>();

                        for (String it : keySet) {

                            // 获取 一天时间里的所有文件路径
                            List<String> paths = mapDatePaths.get(it);

                            List<BaseNode> childNodes = new ArrayList<>();
                            for (String it1 : paths) {
                                childNodes.add(new FileChildNode(it1, true, WeChatClearUtils.getFileLength(it1)));
                            }
                            baseNodes.add(new FileHeaderNode(it, WeChatClearUtils.getFileLength(paths), paths.size(), true, childNodes));
                        }
                        emitter.onNext(baseNodes);
                    }
                }).subscribeOn(Schedulers.io())
                        .subscribe(new Observer<List<BaseNode>>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {

                            }

                            @Override
                            public void onNext(@NonNull List<BaseNode> baseNodes) {
                                postValue(baseNodes);
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        };
    }

    /**
     * 计算选择总大小
     *
     * @param datas
     * @return
     */
    public long getFilesLength(List<BaseNode> datas) {
        List<String> deletes = new ArrayList<>();
        for (int i = 0; i < datas.size(); i++) {
            BaseNode baseNode = datas.get(i);

            if (baseNode instanceof FileHeaderNode) {
                FileHeaderNode imageHeaderNode = (FileHeaderNode) baseNode;
                boolean check = imageHeaderNode.isCheck();
                if (check) {
                    List<BaseNode> childNode = imageHeaderNode.getChildNode();
                    for (int j = 0; j < childNode.size(); j++) {
                        BaseNode baseNode1 = childNode.get(j);
                        if (baseNode1 instanceof FileChildNode) {
                            FileChildNode imageChildNode = (FileChildNode) baseNode1;
                            deletes.add(imageChildNode.getPath());
                        }
                    }
                } else {
                    List<BaseNode> childNode = imageHeaderNode.getChildNode();
                    for (int j = 0; j < childNode.size(); j++) {
                        BaseNode baseNode1 = childNode.get(j);
                        if (baseNode1 instanceof FileChildNode) {
                            FileChildNode imageChildNode = (FileChildNode) baseNode1;
                            boolean check1 = imageChildNode.isCheck();
                            if (check1) {
                                deletes.add(imageChildNode.getPath());
                            }
                        }
                    }
                }
            }
        }
        long fileLength = WeChatClearUtils.getFileLength(deletes);
        return fileLength;
    }

    /**
     * 删除文件 并且带适配器刷新
     *
     * @param datas
     * @param observer
     */
    public void deleteFile(List<BaseNode> datas, Observer<Boolean> observer) {
        Observable.create(new ObservableOnSubscribe<Boolean>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Boolean> emitter) throws Exception {
                List<String> listDelete = new ArrayList<>();
                for (int i = 0; i < datas.size(); i++) {
                    BaseNode baseNode = datas.get(i);
                    if (baseNode instanceof FileHeaderNode) {
                        FileHeaderNode headerNode = (FileHeaderNode) baseNode;
                        boolean check = headerNode.isCheck();
                        // 如果全选了
                        if (check) {
                            // 删除节点下所有文件
                            List<BaseNode> childNode = headerNode.getChildNode();
                            for (int j = 0; j < childNode.size(); j++) {
                                BaseNode baseNodeT = childNode.get(j);
                                if (baseNodeT instanceof FileChildNode) {
                                    FileChildNode childNodeT = (FileChildNode) baseNodeT;
                                    listDelete.add(childNodeT.getPath());
                                    headerNode.setCount(headerNode.getCount() - 1);
                                    headerNode.setLength(headerNode.getLength() - WeChatClearUtils.getFileLength(childNodeT.getPath()));
                                    childNode.remove(j);
                                    remove(childNodeT.getPath());
                                }
                            }
                        } else {
                            List<BaseNode> childNode = headerNode.getChildNode();
                            for (int j = 0; j < childNode.size(); j++) {
                                BaseNode baseNodeT = childNode.get(j);
                                if (baseNodeT instanceof FileChildNode) {
                                    FileChildNode childNodeT = (FileChildNode) baseNodeT;
                                    boolean check1 = childNodeT.isCheck();
                                    if (check1) {
                                        listDelete.add(childNodeT.getPath());
                                        headerNode.setCount(headerNode.getCount() - 1);
                                        headerNode.setLength(headerNode.getLength() - WeChatClearUtils.getFileLength(childNodeT.getPath()));
                                        childNode.remove(j);
                                        remove(childNodeT.getPath());
                                    }
                                }
                            }
                        }
                    }

                    if (baseNode instanceof UpGroupNode) {
                        UpGroupNode upGroupNode = (UpGroupNode) baseNode;

                        List<BaseNode> childNode = upGroupNode.getChildNode();
                        for (int k = 0; k < childNode.size(); k++) {
                            BaseNode baseNodeT = childNode.get(k);
                            if (baseNodeT instanceof UpChildNode) {
                                UpChildNode upChildNode = (UpChildNode) baseNodeT;
                                boolean check = upChildNode.isCheck();
                                if (check) {
                                    listDelete.addAll(upChildNode.getPaths());
                                    childNode.remove(k);
                                    upChildNode.setSize(getFilesLength(childNode));
                                }
                            }
                        }


//                        if (upGroupNode.isCheck()) {
//                            List<BaseNode> childNode = upGroupNode.getChildNode();
//                            for (int k = 0; k < childNode.size(); k++) {
//                                BaseNode baseNodeT = childNode.get(k);
//                                if (baseNodeT instanceof UpChildNode) {
//                                    UpChildNode upChildNode = (UpChildNode) baseNodeT;
//                                    listDelete.addAll(upChildNode.getPaths());
//                                    upGroupNode.setSize(upGroupNode.getSize() - WeChatClearUtils.getFileLength(upChildNode.getPaths()));
//                                    childNode.remove(k);
//                                }
//                            }
//                        } else
//
//                            {
//                            List<BaseNode> childNode = upGroupNode.getChildNode();
//                            for (int k = 0; k < childNode.size(); k++) {
//                                BaseNode baseNodeT = childNode.get(k);
//                                if (baseNodeT instanceof UpChildNode) {
//                                    UpChildNode upChildNode = (UpChildNode) baseNodeT;
//                                    boolean check = upChildNode.isCheck();
//                                    if (check) {
//                                        listDelete.addAll(upChildNode.getPaths());
//                                        childNode.remove(k);
//                                        upChildNode.setSize(getFilesLength(childNode));
//                                    }
//                                }
//                            }
//                        }
                    }
                }
                // 删除文件
                for (String it : listDelete) {
                    // 删除操作
                    boolean delete = WeChatClearUtils.delete(it);

                    remove(it);
                }

                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    /**
     * 移除集合中的元素
     *
     * @param path
     */
    private void remove(String path) {

        Log.e(TAG, "remove: " + path);

        if (friendList.contains(path)) {
            friendList.remove(path);

            Log.e(TAG, "remove: friendList");
        }
        if (cacheList.contains(path)) {
            cacheList.remove(path);
            Log.e(TAG, "remove: cacheList");
        }
        if (rubbishList.contains(path)) {
            rubbishList.remove(path);
            Log.e(TAG, "remove: rubbishList");
        }
        if (videoList.contains(path)) {
            videoList.remove(path);
            Log.e(TAG, "remove: videoList");
        }
        if (imageList.contains(path)) {
            imageList.remove(path);
            Log.e(TAG, "remove: imageList");
        }
        if (voiceList.contains(path)) {
            voiceList.remove(path);
            Log.e(TAG, "remove: voiceList");
        }
        if (fileList.contains(path)) {
            fileList.remove(path);
            Log.e(TAG, "remove: fileList");
        }
        if (emojiList.contains(path)) {
            emojiList.remove(path);
            Log.e(TAG, "remove: emojiList");
        }
    }


    /**
     * 计算立即清理的文件大小
     *
     * @param datas
     * @return
     */
    public long getNowClearFilesLength(List<BaseNode> datas) {


        List<String> deletes = new ArrayList<>();
        for (int i = 0; i < datas.size(); i++) {
            BaseNode baseNode = datas.get(i);

            if (baseNode instanceof UpGroupNode) {
                UpGroupNode upGroupNode = (UpGroupNode) baseNode;

                List<BaseNode> childNode = upGroupNode.getChildNode();
                for (int j = 0; j < childNode.size(); j++) {
                    BaseNode baseNodeT = childNode.get(j);
                    if (baseNodeT instanceof UpChildNode) {
                        UpChildNode upChildNode = (UpChildNode) baseNodeT;
                        boolean checkT = upChildNode.isCheck();
                        if (checkT) {
                            deletes.addAll(upChildNode.getPaths());
                        }
                    }
                }


//                boolean check = upGroupNode.isCheck();
//                if (check) {
//                    List<BaseNode> childNode = upGroupNode.getChildNode();
//                    for (int j = 0; j < childNode.size(); j++) {
//                        BaseNode baseNodeT = childNode.get(j);
//                        if (baseNodeT instanceof UpChildNode) {
//                            UpChildNode upChildNode = (UpChildNode) baseNodeT;
//                            deletes.addAll(upChildNode.getPaths());
//                        }
//                    }
//                } else {
//                    List<BaseNode> childNode = upGroupNode.getChildNode();
//                    for (int j = 0; j < childNode.size(); j++) {
//                        BaseNode baseNodeT = childNode.get(j);
//                        if (baseNodeT instanceof UpChildNode) {
//                            UpChildNode upChildNode = (UpChildNode) baseNodeT;
//                            boolean checkT = upChildNode.isCheck();
//                            if (checkT) {
//                                deletes.addAll(upChildNode.getPaths());
//                            }
//                        }
//                    }
//                }
            }
        }
        long fileLength = WeChatClearUtils.getFileLength(deletes);
        return fileLength;
    }


    /**
     * 清理现有 数据
     */
    public void clear() {
        // 清楚本次统计数据
        totalScanGarbageSize = 0;
        friendList.clear();
        cacheList.clear();
        rubbishList.clear();
        videoList.clear();
        imageList.clear();
        voiceList.clear();
        fileList.clear();
        emojiList.clear();
    }

    /**
     * 获取选择的文件
     *
     * @param datas
     * @return
     */
    public List<String> getSelectFile(List<BaseNode> datas) {
        List<String> result = new ArrayList<>();

        for (int i = 0; i < datas.size(); i++) {
            BaseNode baseNode = datas.get(i);
            if (baseNode instanceof FileHeaderNode) {
                FileHeaderNode fileHeaderNode = (FileHeaderNode) baseNode;
                boolean check = fileHeaderNode.isCheck();
                if (check) {
                    List<BaseNode> childNode = fileHeaderNode.getChildNode();
                    for (int j = 0; j < childNode.size(); j++) {
                        BaseNode baseNode1 = childNode.get(j);
                        if (baseNode1 instanceof FileChildNode) {
                            FileChildNode fileChildNode = (FileChildNode) baseNode1;
                            result.add(fileChildNode.getPath());
                        }
                    }
                } else {
                    List<BaseNode> childNode = fileHeaderNode.getChildNode();
                    for (int j = 0; j < childNode.size(); j++) {
                        BaseNode baseNode1 = childNode.get(j);
                        if (baseNode1 instanceof FileChildNode) {
                            FileChildNode fileChildNode = (FileChildNode) baseNode1;
                            if (fileChildNode.isCheck()) {
                                result.add(fileChildNode.getPath());
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
}